package com.tju.ocean_ecology_website.service.impl;

import com.tju.ocean_ecology_website.dto.LoginRequest;
import com.tju.ocean_ecology_website.dto.LoginResponse;
import com.tju.ocean_ecology_website.dto.RegisterRequest;
import com.tju.ocean_ecology_website.dto.RegisterResponse;
import com.tju.ocean_ecology_website.entity.User;
import com.tju.ocean_ecology_website.mapper.UserMapper;
import com.tju.ocean_ecology_website.security.JwtTokenUtil;
import com.tju.ocean_ecology_website.service.AuthService;
import com.tju.ocean_ecology_website.util.PasswordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * 认证服务实现类
 */
@Slf4j
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        authenticate(loginRequest.getUsername(), loginRequest.getPassword());
        log.info("认证成功！");

        // 加载用户详情
        final UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());

        // 生成JWT令牌
        final String token = jwtTokenUtil.generateToken(userDetails);

        // 获取用户信息
        User user = userMapper.findByUsername(loginRequest.getUsername());

        // 构建用户信息
        LoginResponse.UserInfo userInfo = LoginResponse.UserInfo.builder()
                .id(user.getId())
                .username(user.getUsername())
                .name(user.getName())
                .role(user.getRole())
                .avatar(user.getAvatar())
                .build();

        // 构建登录响应
        return LoginResponse.builder()
                .token(token)
                .user(userInfo)
                .build();
    }

    @Override
    public User register(RegisterRequest registerRequest) {
        // 检查用户名是否已存在
        if (userMapper.findByUsername(registerRequest.getUsername()) != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查邮箱是否已存在
        if (userMapper.findByEmail(registerRequest.getEmail()) != null) {
            throw new RuntimeException("邮箱已存在");
        }

        // 验证角色是否有效
        Integer role = registerRequest.getRole();
        if (role != null && role != 0 && role != 2 && role != 3) {
            throw new RuntimeException("无效的角色值，必须是0（普通用户）、2（志愿者）或3（组织）");
        }

        // 创建新用户
        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword())); // 密码加密
        user.setName(registerRequest.getName());
        user.setEmail(registerRequest.getEmail());
        user.setPhone(registerRequest.getPhone());
        user.setRole(registerRequest.getRole()); // 使用请求中的角色
        user.setStatus(1); // 激活状态
        Date now = new Date();
        user.setCreateTime(now);
        user.setUpdateTime(now);

        // 保存用户
        userMapper.insert(user);

        return user;
    }

    @Override
    public RegisterResponse registerAndGetResponse(RegisterRequest registerRequest) {
        // 调用原有的注册方法
        User user = register(registerRequest);

        // 构建注册响应
        return RegisterResponse.builder()
                .id(user.getId())
                .username(user.getUsername())
                .name(user.getName())
                .email(user.getEmail())
                .phone(user.getPhone())
                .role(user.getRole())
                .createdAt(user.getCreateTime())
                .build();
    }

    /**
     * 认证用户
     */
    private void authenticate(String username, String password) {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            throw new DisabledException("USER_DISABLED", e);
        } catch (BadCredentialsException e) {
            throw new BadCredentialsException("INVALID_CREDENTIALS", e);
        }
    }
}
